// IPlugin.h
“”“
这个类定义了 Redhat 虚拟机插件的接口。
”“”
#ifndef IPLUGIN_H
#define IPLUGIN_H

#include <string>
#include <vector>
#include <memory>

namespace ebackup {
namespace plugins {

class IPlugin {
public:
    virtual ~IPlugin() = default;

    virtual void initialize() = 0;
    virtual void shutdown() = 0;

    virtual std::vector<std::string> getSupportedOperations() const = 0;
    virtual bool performOperation(const std::string& operation, const std::map<std::string, std::string>& parameters) = 0;
};

} // namespace plugins
} // namespace ebackup

#endif // IPLUGIN_H



// PluginManager.h
#ifndef PLUGIN_MANAGER_H
#define PLUGIN_MANAGER_H

#include <map>
#include <vector>
#include <string>
#include <dlfcn.h>
#include <mutex>

namespace ebackup {
namespace plugins {

class PluginManager {
public:
    PluginManager();
    ~PluginManager();

    void loadPlugin(const std::string& pluginPath);
    void unloadPlugin(const std::string& pluginPath);
    void unloadAllPlugins();
    void initializePlugins();
    void shutdownPlugins();

    std::shared_ptr<IPlugin> getPlugin(const std::string& pluginName);

private:
    std::map<std::string, std::shared_ptr<IPlugin>> loadedPlugins;
    std::mutex pluginMutex;

    void* loadPluginLibrary(const std::string& pluginPath);
    std::shared_ptr<IPlugin> createPluginInstance(void* handle);
};

} // namespace plugins
} // namespace ebackup

#endif // PLUGIN_MANAGER_H





// PluginManager.cpp
#include "PluginManager.h"
#include <iostream>
#include <cstring>

namespace ebackup {
namespace plugins {

PluginManager::PluginManager() {
}

PluginManager::~PluginManager() {
    unloadAllPlugins();
}

void PluginManager::loadPlugin(const std::string& pluginPath) {
    std::lock_guard<std::mutex> lock(pluginMutex);

    if (loadedPlugins.find(pluginPath) != loadedPlugins.end()) {
        std::cerr << "Plugin already loaded: " << pluginPath << std::endl;
        return;
    }

    void* handle = loadPluginLibrary(pluginPath);
    if (handle == nullptr) {
        return;
    }

    std::shared_ptr<IPlugin> plugin = createPluginInstance(handle);
    if (plugin == nullptr) {
        dlclose(handle);
        return;
    }

    loadedPlugins[pluginPath] = plugin;

    std::cout << "Plugin loaded: " << pluginPath << std::endl;
}

void PluginManager::unloadPlugin(const std::string& pluginPath) {
    std::lock_guard<std::mutex> lock(pluginMutex);

    auto it = loadedPlugins.find(pluginPath);
    if (it != loadedPlugins.end()) {
        it->second->shutdown();
        loadedPlugins.erase(it);
        std::cout << "Plugin unloaded: " << pluginPath << std::endl;
    }
}

void PluginManager::unloadAllPlugins() {
    std::lock_guard<std::mutex> lock(pluginMutex);

    for (auto& pair : loadedPlugins) {
        pair.second->shutdown();
    }
    loadedPlugins.clear();
}

void PluginManager::initializePlugins() {
    std::lock_guard<std::mutex> lock(pluginMutex);

    for (auto& pair : loadedPlugins) {
        pair.second->initialize();
    }
}

void PluginManager::shutdownPlugins() {
    std::lock_guard<std::mutex> lock(pluginMutex);

    for (auto& pair : loadedPlugins) {
        pair.second->shutdown();
    }
}

std::shared_ptr<IPlugin> PluginManager::getPlugin(const std::string& pluginName) {
    std::lock_guard<std::mutex> lock(pluginMutex);

    auto it = loadedPlugins.find(pluginName);
    if (it != loadedPlugins.end()) {
        return it->second;
    }
    return nullptr;
}

void* PluginManager::loadPluginLibrary(const std::string& pluginPath) {
    void* handle = dlopen(pluginPath.c_str(), RTLD_NOW);
    if (handle == nullptr) {
        std::cerr << "Failed to load plugin: " << dlerror() << std::endl;
    }
    return handle;
}

std::shared_ptr<IPlugin> PluginManager::createPluginInstance(void* handle) {
    typedef IPlugin* (*CreatePluginFunc)();
    CreatePluginFunc createPlugin = (CreatePluginFunc)dlsym(handle, "createPlugin");
    if (createPlugin == nullptr) {
        std::cerr << "Failed to get plugin factory: " << dlerror() << std::endl;
        return nullptr;
    }
    return std::shared_ptr<IPlugin>(createPlugin());
}

} // namespace plugins
} // namespace ebackup